//AES加密，（目前库只支持AES128，iv长度16位,key长度16位）128的keysize=16，192keysize=24，256keysize=32,
import 'dart:convert';
import 'dart:ffi';
import 'dart:math';
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';

// import 'package:flutter/foundation.dart';

class Encrypt {
  //AES加密
  static _aesEncrypt(plainText, String keyString, String ivString) {
    try {
      final key = Key.fromUtf8(keyString);
      final iv = IV.fromUtf8(ivString);
      //AES-128-PKCS7-CBC
      final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
      final encrypted = encrypter.encrypt(plainText, iv: iv);

      return encrypted.base64;
    } catch (err) {
      return "";
    }
  }

  //AES解密
  static dynamic _aesDecrypt(encrypted, String keyString, String ivString) {
    try {
      final key = Key.fromUtf8(keyString);
      final iv = IV.fromUtf8(ivString);
      final encrypter = Encrypter(AES(key, mode: AESMode.cbc));
      final decrypted = encrypter.decrypt64(encrypted, iv: iv);

      return decrypted;
    } catch (err) {
      return encrypted;
    }
  }

  //处理字节数据位置
  static String _reversalWithBase64String(
      String base64String, List<int> newOrder) {
    Uint8List bytes = Uint8List.fromList(base64Decode(base64String));
    var length = bytes.length;
    var chunkSize = (length / 4).truncate();
    List<Uint8List> chunks = [
      bytes.sublist(0, chunkSize),
      bytes.sublist(chunkSize, 2 * chunkSize),
      bytes.sublist(2 * chunkSize, 3 * chunkSize),
      bytes.sublist(3 * chunkSize)
    ];

    List<int> reorderedChunks = [];
    for (var index in newOrder) {
      reorderedChunks = reorderedChunks + chunks[index];
    }

    Uint8List mergedData = Uint8List.fromList(reorderedChunks);

    String finalBase64String = base64Encode(mergedData);
    return finalBase64String;
  }

  //http请求数据加密
  static ({String base64String, String iv}) encryptString(String jsonString) {
    int timestamp = (DateTime.now().millisecondsSinceEpoch / 1000).toInt();
    int yu = timestamp % 300;
    int min = timestamp - yu;
    int max = min + 300;
    int seed = ((min + max) / 2).toInt();

    String charset =
        "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
    int length = 16;
    int a = 1664525;
    int c = 1013904223;
    int m = 0x100000000;
    int x = seed;
    String key = "";
    for (int i = 0; i < length; i++) {
      x = (a * x + c) % m;
      int starIndex = x % charset.length;
      key = key + charset.substring(starIndex, starIndex + 1);
    }

    String ivString = "";
    for (int i = 0; i < length; i++) {
      int randomInt = Random().nextInt(charset.length);
      ivString = ivString + charset[randomInt];
    }

    //根据key、iv、传参，加密
    //AES加密
    var aesString = _aesEncrypt(jsonString, key, ivString);

    //截取组装
    return (
      base64String: _reversalWithBase64String(aesString, [3, 1, 0, 2]),
      iv: ivString
    );
  }

  //http请求数据解密
  static decryptString(String aesString, String iv) {
    String base64String = _reversalWithBase64String(aesString, [2, 1, 3, 0]);

    int timestamp = (DateTime.now().millisecondsSinceEpoch / 1000).toInt();
    int yu = timestamp % 300;
    int min = timestamp - yu;
    int max = min + 300;
    int seed = ((min + max) / 2).toInt();

    String charset =
        "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
    int length = 16;
    int a = 1664525;
    int c = 1013904223;
    int m = 0x100000000;
    int x = seed;
    String key = "";
    for (int i = 0; i < length; i++) {
      x = (a * x + c) % m;
      int starIndex = x % charset.length;
      key = key + charset.substring(starIndex, starIndex + 1);
    }

    //根据key、iv、传参，加密

    String jsonString = _aesDecrypt(base64String, key, iv);
    return jsonString;
  }
}
